//#ifndef DECLARATIONS_H_
//#define DECLARATIONS_H_

using namespace std;

#include<iostream>
#include<vector>
#include<pthread.h>
#include<signal.h>
#include<queue>
#include<map>
#include<stdint.h>
#include<inttypes.h>
#include<string.h>
#include<string>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include<sys/stat.h>
#include <algorithm>
#include <iterator>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<errno.h>
#include<strings.h>
#include <set>
#include<netinet/in.h>
#include <math.h>
#include <fstream>
#include <iostream>
#include <unistd.h>
#include <time.h>
#include <iomanip>
#include <bitset>
#include <list>
#include <math.h>
#include <bitset>

//#endif 


#include <openssl/sha.h>
#include "LogFile.h"
#include "fileConfig.h"

#include "StartUpConfigurationFile.h"
#include "IniParser.h"

#ifndef min
#define min(A,B) (((A)>(B)) ? (B) : (A))
#endif 


#define helloMessageType 0xFA
#define joinRequestMessageType 0xFC
#define joinResponseMessageType 0xFB
#define keepAliveMessageType 0xF8
#define checkResponseMessageType 0xF5
#define checkRequestMessageType 0xF6
#define statusRequestMessageType 0xAC
#define statusResponseMessageType 0xAB
#define notifyMessageType 0xF7
#define statusNeighbourMessageType 0x01


#define UNKNOWN			0
#define USERSHUTDOWN	1
#define UNEXPECTEDKILL  2
#define SELFRESTART		3
#define STATUSNB		4
#define SHUTDOWN		5
#define CMD_MAX_TOKENS  30
#define STORE			6
#define SEARCHFILE		7	
#define SEARCHSHA1		8
#define SEARCHKEYWORD	9
#define STATUSFILE		10
#define GET				11
#define DELETE			12



struct Header
{
	uint8_t messageType;
	unsigned char* uoid;
	uint8_t ttl;
	uint8_t reserved;
	unsigned int dataLength;
};

struct Messages																// Messages in queue
{
	int socketDescripter;
	char* Header;
	char* Data;
};

struct HelloMessage
{
	uint16_t port;
	char* hostname;
};

struct JoinRequestMessage
{
	unsigned long int location;
	uint16_t port;
	char* hostname;

};

struct JoinResponseMessage
{
	unsigned char* uoid;
	uint32_t distance;
	uint16_t port;
	char* hostname;
};

struct CheckResponseMessage
{
	unsigned char* uoid;
};

struct StatusResponseMessage
{
	unsigned char* uoid;
	uint16_t hostInfoLength;
	uint16_t port;
	char* hostname;
	char* data;
};


extern void GetUOID(char *node_inst_id, char *obj_type, unsigned char *uoid_buf, unsigned int uoid_buf_sz);
extern void commandLine(int argc, char *argv[]);
extern void *server(void *ptr);
extern void *child(void *ptr);
extern void *connect(void *ptr);
extern void *connectJoin(void *ptr);
extern void *read(void *ptr);
extern void *write(void *ptr);
extern void *dispatcher(void *ptr);
extern void *msgLifeTimer(void *ptr);
extern void *keepAlive(void *ptr);
extern void *autoShutdown(void *ptr);
extern void printUOID(unsigned char *uoid);
extern void *checkThreadFunction(void *ptr);

extern string checkUOID;


extern void JoinToTheNetwork();											// Fresh start function for a REGULAR node to join or a Participating node



extern Header createHeader(uint8_t messageType, unsigned int dataLength);
extern HelloMessage sendHello();
extern JoinRequestMessage sendJoinRequest();
extern JoinResponseMessage sendJoinResponse();
extern JoinResponseMessage sendJoinReponse(unsigned char* senderuoid, uint32_t distance);
extern StatusResponseMessage sendStatusResponse(unsigned char* senderuoid, char* myData,int recordLengthIndex);
extern CheckResponseMessage sendCheckResponse(unsigned char* senderuoid);

extern void enterLogData(Messages msg);
extern void enterLogMessage(Messages msg, char type, struct timeval t);



extern pthread_t serverThread;															// Server thread for server running on given node
extern pthread_t dispatcherThread;
extern pthread_t msgLifeTimerThread;
extern pthread_t keepAliveThread;
extern pthread_t autoShutdownThread;
extern pthread_t commandLineThread;
extern pthread_t checkThread;


extern int iretServerThread; 
extern int iretConnectThread;
extern int iretReadThread;
extern int iretWriteThread;
extern int iretChildThread;
extern int iretDispatcherThread;
extern int iretMsgLifeTimerThread;
extern int iretKeepAliveThread;
extern int iretAutoShutdownThread;


extern bool IsBeaconNode;
extern int resetFlag;																	// set if node is reset (if it has never been started before)
extern char *startupFile;															// startup.ini
extern bool resetKeepAlive[512];
extern bool joinToTheNetworkFlag;
extern bool shutdownFlag;
extern bool ctrlFlag;
extern bool checkFlag;
extern bool checkActive;

extern struct timeval statusFirst, statusLast;

extern bool deleteConnection[512];

extern pthread_mutex_t NeighborList;
extern pthread_mutex_t ReadQueue;
extern pthread_mutex_t WriteQueue[512];
extern pthread_mutex_t UoidMap;
extern pthread_mutex_t ResetKeepAlive[512];
extern pthread_mutex_t deleteConnectionLock[512];



extern pthread_cond_t  condition_var_Read;
extern pthread_cond_t  condition_var_Write[512];



extern list<Messages> writeQueue[512];											// write queue different for all write threads
extern list<Messages> readQueue;													// read queue common for all read threads

extern map<string,int> checkUoidSockDesc;

extern StartUpConfigurationFile node;

extern fileConfig fileObject;
extern char bitvectorBuffer[256];
extern uint16_t connectBeaconPort;

